package com.vcs.web;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.*;
import com.vcs.domain.Job;
import com.vcs.domain.Client;
import com.vcs.domain.JobApplication;
import com.vcs.domain.Jobseeker;
import com.vcs.dao.*;
import com.vcs.util.MailUtil;
import com.vcs.util.Util;
import com.vcs.util.VcsConstants;

@SuppressWarnings("serial")
public class JobAction extends ActionSupport implements ModelDriven<Job>,
		SessionAware, RequestAware, ValidationAware {

	private Log log = LogFactory.getLog(JobAction.class);
	private Job job = new Job();
	private List<Job> jobList = new ArrayList<Job>();
	private JobDAO jobDao = new JobDAOImpl();
	// this should not be here
	JobseekerDAO jobseekerDao = new JobseekerDAOImpl();
	private Map<String, Object> sessionMap;
	private Map<String, Object> requestMap;

	@Override
	public Job getModel() {
		return job;
	}

	@Override
	public void setSession(Map<String, Object> sessionMap) {
		this.sessionMap = sessionMap;
	}

	public String save() {

		// if any client has not logged in then don't save job
		if (sessionMap.get("client") != null) {
			// get client id from session and set in posted job
			Long cid = ((Client) sessionMap.get("client")).getId();
			job.setClientId(cid);
			// make job ACTIVE
			job.setStatus(true);
			// capture job post date to check and disable it later
			job.setJobPostDate(new java.util.Date());
			// set Client's name

			if (job.getCompanyName() == null
					|| job.getCompanyName().length() == 0) {
				job.setCompanyName(((Client) sessionMap.get("client"))
						.getCompanyName());
			}

			// if client did not enter company profile then it should be default
			// company profile
			if (job.getCompanyProfile().equals("")
					|| job.getCompanyProfile() == null) {
				job.setCompanyProfile(((Client) sessionMap.get("client"))
						.getCompanyProfile());
			}
			// job.setContactNumber(contactNumber)

			log.debug("Job is: [ " + job + " ]");
			// validate post job form
			validatePostJobForm();
			if (hasFieldErrors()) {
				return INPUT;
			}

			jobDao.save(job);

			// Create a new thread and call MailUtil.sendMail() to inform admin
			// about a new job posting
			PrepareAndSendMail psm = new PrepareAndSendMail();
			Thread sendMailThread = new Thread(psm);
			sendMailThread.start();

		} else {
			// it means no client has logged in.
			log.info("XXX Someone tried to post a job without logging in.");
		}

		return SUCCESS;
	}

	public String update() {
		jobDao.update(job);
		return SUCCESS;
	}

	// job should not be really deleted. it's status should be updated to false
	public String delete() {
		log.info("delete()...");
		Client client = (Client) sessionMap.get("client");
		// if client is an Admin he should be able to delete any job. otherwise
		// normal client should delete jobs posted by him only
		if (client != null
				&& client.getRole().equalsIgnoreCase(VcsConstants.ADMIN)) {
			log.info("Inside if..");
			Long jobId = (Long) requestMap.get("jobId");
			jobDao.delete(jobId);
			return SUCCESS;
		} else if (client != null
				&& client.getRole().equalsIgnoreCase(VcsConstants.CLIENT)) {
			log.info("Inside else..");
			Long jobId = (Long) requestMap.get("jobId");
			log.info("jobId of job to be deleted:" + jobId);
			Long jobOwner = jobDao.getJobOwner(jobId);
			log.info("Owner of Job no: " + jobId + " is client No: " + jobOwner);
			Long clientId = client.getId();
			log.info("jobOwner " + jobOwner);
			log.info("clientId: " + clientId);
			// if owner of job is same as logged in client only then the job can
			// be deleted
			if (clientId.compareTo(jobOwner) == 0) {
				log.info("Job owner is same as the logged in user. This job will be deleted");
				jobDao.delete(jobId);
			} else {
				log.info("current user is not the owner of this job. JOB CAN NOT BE DELETED");
			}
			return SUCCESS;
		}

		return INPUT;
	}

	public String listAllJobs() {
		log.info("listAllJobs()...");
		jobList = jobDao.listJobs();
		log.debug("Jobs fetched from database : [ " + jobList.size() + " ]");
		// Sort jobs based on Job Id
		Collections.sort(jobList,new Comparator<Object>(){

			@Override
			public int compare(Object first, Object second) {
				Job a = (Job) first;
				Job b = (Job) second;
				if(a.getJobId() > b.getJobId() ){
					return -1;
				}else if (a.getJobId() < b.getJobId()){
				return 1;
				}else{
					return 0;
				}
			}
		});
		
		requestMap.put("jobList", jobList);
		Jobseeker js = (Jobseeker) sessionMap.get("js");
		if (js != null) {
			log.debug("Some jobseeker has logged in - Fetching list of applied jobs");
			List<Long> appliedJobsIdList = jobseekerDao.getAppliedJobIdList(js
					.getJobseekerId());
			requestMap.put("appliedJobsIdList", appliedJobsIdList);
			log.debug("-------> " + appliedJobsIdList);
		}

		return SUCCESS;
	}

	public String listJobsByClient() {
		log.info("listJobsByClient()...");
		Long clientId = ((Client) sessionMap.get("client")).getId();
		log.info("Client id is: [ " + clientId + " ]");
		List<Job> jobList = jobDao.listJobsByClientId(clientId);
		// set this jobList in request scope
		requestMap.put("jobList", jobList);
		return SUCCESS;
	}

	public List<Job> getJobList() {
		return jobList;
	}

	public void setJobList(List<Job> jobList) {
		this.jobList = jobList;
	}

	@Override
	public void setRequest(Map<String, Object> requestMap) {
		this.requestMap = requestMap;
	}

	/**
	 * this method does server side validation of job post form
	 */

	/*@Override
	public void validate() {
		log.info("********************************************************Entered Validate method");
		if (job.getJobDescription().length() == 0) {
			addFieldError("jobDescription", "You must provide job description");
			addActionError("Please correct errors before submitting the form");
		}
		if (job.getJobTitle().length() == 0) {
			addFieldError("jobTitle", "Please provide Job Title");
		}

	}*/
	
	
	public String getCurrentJobApplications(){
		log.info("getCurrentJobApplications()...");
		List<JobApplication> getAllJobApplications = jobDao.getAllJobApplications();
		// Fetch jobIds and add in a list
		List<Long> jobIdList = new ArrayList<Long>();
		for(JobApplication app : getAllJobApplications){
			jobIdList.add(app.getJobId());
		}
		// pass jobidList to get full details of these jobs.		
		List<Job> jobList =  jobDao.getJobListById(jobIdList);
		Collections.sort(jobList);
		Collections.sort(getAllJobApplications);
		
		requestMap.put("getAllJobApplications", getAllJobApplications);
		requestMap.put("jobList", jobList);
		requestMap.put("", "");
		return SUCCESS;
	}
		
	/**
	 * Validates fields of post job form.
	 */

	private void validatePostJobForm() {

		if (job.getJobTitle().length() == 0) {
			addFieldError("jobTitle", "You did not enter Job Title");
		}
		if (job.getJobDescription().length() == 0) {
			addFieldError("jobDescription", "You did not enter job description");
		}
		if (job.getKeySkills().length() == 0) {
			addFieldError("keySkills", "You did not enter key skills");
		}
		if (job.getJobRole().length() == 0) {
			addFieldError("jobRole", "You did not enter Job Role");
		}
		
		if(job.getMinCompensation() > job.getMaxCompensation()){
			addFieldError("maxCompensation","Maximum compensation should be greater than Minimum compensation");
		}

		if (job.getEmploymentStatus() == 0) {
			addFieldError("employmentStatus", "Please select Employment Status");
		}

		if (job.getCompanyProfile().length() > 300) {
			addFieldError("companyProfile",
					"Company profile can not be more than 300 charactors long");
		}
		if (job.getCompanyName().length() == 0) {
			addFieldError("companyName", "You did not enter Company Name");
		}
		if (job.getContactName().length() == 0) {
			addFieldError("contactName", "You did not enter Contact Name");
		}

		if (job.getContactNumber() == null) {
			addFieldError("contactNumber", "You did not enter Contact Number");
		} else if (job.getContactNumber() < 1000000000L
				|| job.getContactNumber() > 9999999999L) {
			addFieldError("contactNumber",
					"Contact Number should be a 10 digit Mobile number without Country code");
		}

		// Email
		if(	! Util.isValidEmailAddress(job.getEmailForResponse())){
			addFieldError("emailForResponse",
			"You did not enter correct Email for Response");
		}
		
		/*if (job.getEmailForResponse().length() == 0
				|| job.getEmailForResponse().length() < 7) {
			addFieldError("emailForResponse",
					"You did not enter correct Email for Response");
		} else {
			int atIndex = 0;
			int dotIndex = 0;
			if (job.getEmailForResponse().contains("@")
					&& job.getEmailForResponse().contains(".")) {
				atIndex = job.getEmailForResponse().lastIndexOf("@");
				dotIndex = job.getEmailForResponse().lastIndexOf(".");

				if (dotIndex < atIndex) {
					addFieldError("email",
							"Invalid email. Please provide your correct email address");
				}
			} else {
				addFieldError("email",
						" Invalid email. Please provide your correct email address");
			}
		}*/

	}

}

class PrepareAndSendMail implements Runnable {

	@Override
	public void run() {
		MailUtil mUtil = new MailUtil();
		mUtil.sendMail(
				"myjob.vcs@gmail.com",
				"myjob.vcs@gmail.com",
				"Alert - New Job Posted",
				" Dear Admin,\n \n New Job Posted on portal.\n Please check http://www.vowconsultancy.com/hotjobs.action");

	}

}